package demo.temi.com.porterduffproject;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * @author COCO
 * @date 2018/11/27
 * <p>
 * PorterDuffView关键点：
 * 1.关闭硬件加速
 * 2.创建新图层
 * 3.DST and SRC Bitmap大小要一样
 * 4.SRC的透明区域不要太小，如果SRC无法完全覆盖DST，未覆盖的DST部分仍然会显示出来，效果和预期不一样
 */
public class PorterDuffView extends View {
    private Paint paint;
    private int width;
    private int height;

    public PorterDuffView(Context context) {
        super(context);
        init();
    }

    public PorterDuffView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PorterDuffView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        //初始化画笔
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        this.width = w;
        this.height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //禁用硬件加速
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        //使用离屏绘制
        int layerID = canvas.saveLayer(0, 0, getWidth(), getHeight(), paint, Canvas.ALL_SAVE_FLAG);

        canvas.drawBitmap(createDstBitmap(width, height), 0, 0, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(createSrcBitmap(width, height), 0, 0, paint);
        paint.setXfermode(null);

        //SRC_IN : Keeps the source pixels that cover the destination pixels,discards the remaining source and destination pixels.
        //SRC_OUT: Keeps the source pixels that do not cover destination pixels.Discards source pixels that cover destination pixels. Discards all destination pixels.
        //SRC_ATOP: Discards the source pixels that do not cover destination pixels.Draws remaining source pixels over destination pixels.
        //DST_OUT: Keeps the destination pixels that are not covered by source pixels.Discards destination pixels that are covered by source pixels. Discards all source pixels.
        //DST_IN:  Keeps the destination pixels that cover source pixels,discards the remaining source and destination pixels.
        //DST_ATOP：Discards the destination pixels that are not covered by source pixels.Draws remaining destination pixels over source pixels.

        canvas.restoreToCount(layerID);
    }

    //Dst and Src Bitmap 大小要一致
    public Bitmap createDstBitmap(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint scrPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        scrPaint.setColor(0xFFFFCC44);
        canvas.drawARGB(0, 0, 0, 0);
        canvas.drawCircle(width / 2, height / 2, width / 2, scrPaint);
        return bitmap;
    }

    //Dst and Src Bitmap 大小要一致
    public Bitmap createSrcBitmap(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint dstPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        dstPaint.setColor(0xFF66AAFF);
        canvas.drawARGB(0, 0, 0, 0);//设置颜色的话会导致上下层叠加时会有问题
        canvas.drawRect(new Rect(0, 0, width / 2, height / 2), dstPaint);

        return bitmap;
    }
}
